﻿// 虚函数重写的一些细节：
// 重写的条件本来是虚函数+三同，但是有一些例外
// 1、派生类的重写虚函数可以不加virtual -- （建议大家都加上）
// 2、协变，返回的值可以不同，但是要求返回值必须是父子关系指针和引用
#include<iostream>
using namespace std;
//class Person {
//public:
//	virtual	void BuyTicket() const { cout << "买票-全价" << endl; }
//};
//
//class Student : public Person {/*派生类的重写虚函数可以不加virtual（但是还是建议加上）*/
//public:
//	virtual	void BuyTicket() const { cout << "买票-半价" << endl; }
//};
//void func(const Person* p)
//{
//	p->BuyTicket();
//}
//// 多态条件
//// 1、调用函数是重写的虚函数
//// 2、基类指针或者引用
//
////// 多态，不同对象传递过去，调用不同函数
////// 多态调用看的指向的对象
////// 普通对象，看当前者类型
//int main()
//{
//	Person pp;
//	func(&pp);
//
//	Student st;
//	func(&st);
//
//	return 0;
//}
// 
// 
// 
//class A
//{};
//
//class B : public A
//{};
//
//class Person {
//public:
//	virtual	A* BuyTicket() const { // 协变，返回的值可以不同，但是要求返回值必须是父子关系指针和引用
//		cout << "买票-全价" << endl;
//		return 0;
//	}
//};
//
//class Student : public Person {
//public:
//	virtual B* BuyTicket() const { 
//		cout << "买票-半价" << endl;
//		return 0;
//	}
//};
//void func(const Person* p)
//{
//	p->BuyTicket();
//}
//int main()
//{
//	Person pp;
//	func(&pp);
//
//	Student st;
//	func(&st);
//
//	return 0;
//}

///////////////////////////////////////////////////////////////////////////////////////
// 析构函数可以是虚函数吗？为什么需要是虚函数？
// 析构函数加virtual，是不是虚函数重写？
// 是，因为类析构函数都被处理成destructor这个统一的名字
// 为什么要这么处理呢？因为要让他们构成重写
// 那为什么要让他们构成重写呢？
// 因为下面的场景

//class Person {
//public:
//	  virtual ~Person() { cout << "~Person()" << endl; }
//};
//
//class Student : public Person {
//public:
//	 virtual ~Student() {
//		cout << "~Student()" << endl;
//	}
//};
//int main()
//{
//	//Person p;
//	//Student s;
//	Person* p = new Person;
//	delete p;
//	p = new Student;
//	delete p; // 调用析构函数p->destructor() + 释放空间operator delete（p）
//	//	// 这里我们期望p->destructor()是一个多态调用，而不是普通调用
//	return 0;
//}

//class Car
//{
//public:
//	virtual void Drive() final {}
//};
//
//class Benz :public Car
//{
//public:
//	void Drive(int i) { cout << "Benz-舒适" << endl; }
//};
//
//class Car {
//public:
//	  virtual void Drive() {}
//};
//
//// override 帮助派生检查是否完成重写，如果没有会报错
//class Benz :public Car {
//public:
//	virtual void Drive()override  { cout << "Benz-舒适" << endl; }
//};

 //设计不想被继承类，如何设计？
 //方法1：基类构造函数私有   (C++98)
 //方法2：基类加一个final  （C++11）
//class A
//{
//public:
//	static A CreateObj()
//	{
//		return A();
//	}
//private:
//	A()
//	{}
//};
//
//class B : public A
//{};
//
//int main()
//{
//	// B bb;
//	//A::CreateObj();
//
//	return 0;
//}
//
// 
// 
 //设计不想被继承类，如何设计？
 //方法1：基类构造函数私有   (C++98)
 //方法2：基类加一个final  （C++11）
//class A final
//{
//public:
//private:
//};
//
//class B : public A
//{};
//
//int main()
//{
//	return 0;
//}
// 



// 这里常考一道笔试题：sizeof(Base)是多少？
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//
//	virtual void Func2()
//	{
//		cout << "Func1()" << endl;
//	}
//
//
//	void Func3()
//	{
//		cout << "Func1()" << endl;
//	}
//
//
//};
//
//int main()
//{
//	cout << sizeof(Base) << endl;
//
//	Base b1;
//
//	return 0;
//}
//


//class Person {
//public:
//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
//
//	int _a = 1;
//};
//
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-半价" << endl; }
//	int _b = 1;
//};
//
//void Func(Person& p)
//{
//	// 符合多态，运行时到指向对象的虚函数表中找调用函数的地址
//	p.BuyTicket();
//}
//
//int main()
//{
//	Person Mike;
//	Func(Mike);
//
//	Student Johnson;
//	Func(Johnson);
//
//	return 0;
//}
// 
// 
// 
// 
// 
//class A
//{
//public:
//	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//	virtual void test() { func(); }
//};
//
//class B : public A
//{
//public:
//	void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//};
//
//int main(int argc, char* argv[])
//{
//	B* p = new B;
//	p->test();
//	return 0;
//}

//A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确



//class A
//{
//public:
//    virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//};
//
//class B : public A
//{
//public:
//    void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//    virtual void test() 
//    { 
//        func();
//    }
//};
//
//int main(int argc, char* argv[])
//{
//    B* p = new B;
//    p->test();
//    return 0;
//}




 //class Person {
	//public:
	//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
	//
	//	virtual void Func1() {}
	//
	//	virtual void Func2() {}
	//protected:
	//	int _a = 0;
	//};
	//
	//class Student : public Person {
	//public:
	//	virtual void BuyTicket() { cout << "买票-半价" << endl; }
	//protected:
	//	int _b = 1;
	//};
	//void Func(Person* p)
	//{
	//	p->BuyTicket();
	//}
	//int main()
	//{
	//	Person ps;
	//	Student st;

	//	Func(&st);	
	//	Func(&ps);
	//	ps = st;
	//	Person* ptr = &st;
	//	Person& ref = st;
	//
	//	return 0;
	//}


//int main()
//{
//	Person ps;
//	Student st;
//
//	int a = 0;
//	printf("栈：%p\n", &a);
//
//	static int b = 0;
//	printf("静态区：%p\n", &b);
//
//	int* p = new int;
//	printf("堆：%p\n", p);
//
//	const char* str = "hello world";
//	printf("常量区：%p\n", str);
//
//	printf("虚表1：%p\n", *((int*)&ps));
//	printf("虚表2：%p\n", *((int*)&st));
//
//
//	return 0;
//}


//class Person {
//	public:
//		virtual void BuyTicket() { cout << "买票-全价" << endl; }
//	
//		virtual void Func1() 
//		{
//			cout << "Person::Func1()" << endl;
//		}
//	
//		virtual void Func2() 
//		{
//			cout << "Person::Func2()" << endl;
//		}
//	
//	protected:
//		int _a = 0;
//	};
//	
//	class Student : public Person {
//	public:
//		virtual void BuyTicket() { cout << "买票-半价" << endl; }
//	
//		virtual void Func3()
//		{
//			cout << "Student::Func3()" << endl;
//		}
//	protected:
//		int _b = 1;
//	};
//	
//	typedef void(*FUNC_PTR) ();/*将void(*)()定义为FUNC_PTR，是空返回值空参数的函数指针*/
//
//	// 打印函数指针数组
//	// void PrintVFT(FUNC_PTR table[])
//	void PrintVFT(FUNC_PTR* table)/*table就相当于虚函数表*/
//	{
//		for (size_t i = 0; table[i] != nullptr; i++)/*在vs中虚函数表中以空作为结尾*/
//		{
//			printf("[%d]:%p->", i, table[i]);
//			FUNC_PTR f = table[i];
//			f();/*调用每个虚函数*/
//			printf("\n");
//		}
//	}
//
//	int main()
//	{
//		Person ps;
//		Student st;
//	
//		int vft1 = *((int*)&ps);/*首先取对象头四个字节的内容，内容正是虚函数表指针的地址。
//								然后解引用，就可以读取到虚函数表指针，最后转换成int类型存储*/
//
//		PrintVFT((FUNC_PTR*)vft1);
//	
//		int vft2 = *((int*)&st);
//		PrintVFT((FUNC_PTR*)vft2);
//	
//		return 0;
//	}


//class Person {
//	public:
//		virtual void BuyTicket() { cout << "买票-全价" << endl; }
//	
//		virtual void Func1() 
//		{
//			cout << "Person::Func1()" << endl;
//		}
//	
//		virtual void Func2() 
//		{
//			cout << "Person::Func2()" << endl;
//		}
//	
//	protected:
//		int _a = 0;
//	};
//	
//	class Student : public Person {
//	public:
//		virtual void BuyTicket() { cout << "买票-半价" << endl; }
//	
//		virtual void Func3()
//		{
//			cout << "Student::Func3()" << endl;
//		}
//	protected:
//		int _b = 1;
//	};
//// 多态：
//// 静态(编译时)的多态，函数重载
//// 动态(运行时)的多态，继承，虚函数重写，实现的多态
//int main()
//{
//	int i = 1;
//	double d = 1.1;
//	cout << i << endl;
//	cout << d << endl;
//
//	Person ps;
//	Person* ptr = &ps;
//
//	ps.BuyTicket();
//	ptr->BuyTicket();
//
//	return 0;
//}






//typedef void(*FUNC_PTR) ();/*将void(*)()定义为FUNC_PTR，是空返回值空参数的函数指针*/
//
//// 打印函数指针数组
//// void PrintVFT(FUNC_PTR table[])
//void PrintVFT(FUNC_PTR* table)/*table就相当于虚函数表*/
//{
//	for (size_t i = 0; table[i] != nullptr; i++)/*在vs中虚函数表中以空作为结尾*/
//	{
//		printf("[%d]:%p->", i, table[i]);
//		FUNC_PTR f = table[i];
//		f();/*调用每个虚函数*/
//		printf("\n");
//	}
//}
//
//class Base1 {
//public:
//	virtual void func1() { cout << "Base1::func1" << endl; }
//	virtual void func2() { cout << "Base1::func2" << endl; }
//private:
//	int b1;
//};
//
//class Base2 {
//public:
//	virtual void func1() { cout << "Base2::func1" << endl; }
//	virtual void func2() { cout << "Base2::func2" << endl; }
//private:
//	int b2;
//};
//
//class Derive : public Base1, public Base2 {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//private:
//	int d1;
//};
//
//int main()
//{
//	Derive d;
//	Base1 a;
//	Base2 b;
//	Base1* ptr1 = &d;
//	ptr1->func1();
//
//	Base2* ptr2 = &d;
//	ptr2->func2();
//
//	Derive* ptr3 = &d;
//	ptr3->func1();
//	PrintVFT((FUNC_PTR*)*((int*)&d));
//	PrintVFT((FUNC_PTR*)*((int*)((char*)&d + sizeof(Base1))));
//	return 0;
//}


//#include <iostream>
//
//using namespace std;
//
////抽象类
//class Person
//{
//public:
//	//纯虚函数
//	virtual void func(int a = 10) = 0 { cout << "Person a: " << a << endl; }
//};
//
//int main()
//{
//	//纯虚函数无法实例化对象
//	Person p;
//	Person pp = new Person();	//也不能new出对象
//	return 0;
//}


#include <iostream>
#include <string>
using namespace std;
//
//class Person
//{
//public:
//	Person(const string& name = string())
//		:_name(name)
//	{}
//
//	virtual void func() = 0 {};
//protected:
//	string _name;
//};
//
//class Student : public Person
//{
//public:
//	Student(const string& name = string())
//		:Person(name)
//	{}
//
//	//子类继承抽象类后，需要重写纯虚函数，否则仍然是抽象类
//	virtual void func() {};
//};
//
//int main()
//{
//	//抽象类无法直接实例化对象
//	//Person p("newnew");
//
//	Student s("newnew");
//	return 0;
//}

//
//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//public:
//	/*virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}*/
//};
//class BMW :public Car
//{
//public:
//	/*/virtual void Drive()
//	{
//		cout << "BMW-操控" << endl;
//	}*/
//};
//int main()
//{
//	Car* pBenz = new Benz;
//	pBenz->Drive();
//	Car* pBMW = new BMW;
//	pBMW->Drive();
//}



//class A
//{
//public:
//	virtual void func1()
//	{
//		cout << "A::func1" << endl;
//	}
//public:
//	int _a;
//};
//
////class B : public A
//class B : virtual public A
//{
//public:
//	virtual void func1()
//	{
//		cout << "B::func1" << endl;
//	}
//
//	virtual void func2()
//	{
//		cout << "B::func2" << endl;
//	}
//public:
//	int _b;
//};
//
////class C : public A
//class C : virtual public A
//{
//public:
//	virtual void func1()
//	{
//		cout << "C::func1" << endl;
//	}
//
//	virtual void func2()
//	{
//		cout << "C::func2" << endl;
//	}
//public:
//	int _c;
//};
//
//class D : public B, public C
//{
//public:
//	virtual void func1()
//	{
//		cout << "D::func1" << endl;
//	}
//
//	virtual void func3()
//	{
//		cout << "D::func3" << endl;
//	}
//public:
//	int _d;
//};

//int main()
//{
//	D d;
//	d.B::_a = 1;
//	d.C::_a = 2;
//	d._b = 3;
//	d._c = 4;
//	d._d = 5;
//
//	return 0;
//}



//
//#include<iostream>
//using namespace std;
//typedef void(*FUNC_PTR) ();/*将void(*)()定义为FUNC_PTR，是空返回值空参数的函数指针*/
//
//// 打印函数指针数组
//// void PrintVFT(FUNC_PTR table[])
//void PrintVFT(FUNC_PTR* table)/*table就相当于虚函数表*/
//{
//	for (size_t i = 0; table[i] != nullptr; i++)/*在vs中虚函数表中以空作为结尾*/
//	{
//		printf("[%d]:%p->", i, table[i]);
//		FUNC_PTR f = table[i];
//		f();/*调用每个虚函数*/
//		printf("\n");
//	}
//}
//
//class A
//{
//public:
//	virtual void func1()
//	{
//		cout << "A::func1" << endl;
//	}
//public:
//	int _a;
//};
//
////class B : public A
//class B :  public A
//{
//public:
//	virtual void func1()
//	{
//		cout << "B::func1" << endl;
//	}
//
//	virtual void func2()
//	{
//		cout << "B::func2" << endl;
//	}
//public:
//	int _b;
//};
//
////class C : public A
//class C :  public A
//{
//public:
//	virtual void func1()
//	{
//		cout << "C::func1" << endl;
//	}
//
//	virtual void func2()
//	{
//		cout << "C::func2" << endl;
//	}
//public:
//	int _c;
//};
//
//class D : public B, public C
//{
//public:
//	virtual void func1()
//	{
//		cout << "D::func1" << endl;
//	}
//	virtual void func2()
//	{
//		cout << "D::func2" << endl;
//	}
//	virtual void func3()
//	{
//		cout << "D::func3" << endl;
//	}
//public:
//	int _d=2;
//};
//
//int main()
//{
//	D d;
//	//A* ptr = new D;
//	B* ptr1 = new D;
//	C* ptr2 = new D;
//	//PrintVFT((FUNC_PTR*)*((int*)ptr));
//	PrintVFT((FUNC_PTR*)*((int*)ptr1));
//	PrintVFT((FUNC_PTR*)*((int*)ptr2));
//	//ptr->func1();
//	ptr1->func1();
//	ptr2->func1();
//	return 0;
//}
